<?php
namespace app\home\controller;
use app\BaseController;
use Elasticsearch\ClientBuilder;
use think\App;
use think\facade\Config;
use think\facade\Db;

class Es extends BaseController
{
    protected $client;
    public $index_name='index';
    public $type='type';


    public function __construct(App $app)
    {
        parent::__construct($app);
        if(!$this->client){
            $this->client = ClientBuilder::create()->setHosts(['http://120.78.239.19:9200'])->build();
        }
    }

    public function index()
    {
        $balance = Db::name('branch ')->select();

    }

    /**
     * @return array|callable
     */
    public function create_index()
    {
        // 只能创建一次
        $params = [
            'index'  => 'index',
            'type'   => 'type',
            'client' => [ 'ignore' => [400, 404] ]
        ];
        return $this->client->index($params);
    }

    /**mysql涉及到搜索的数据插入文档
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function sync(){
        $list = Db::name('branch ')->select();
        foreach ($list as $k => $v) {
            $r = $this->add_doc($v['id'],$v);
        }
    }

    /**添加文档
     * @param string $id
     * @param array $doc 跟创建文档结构时properties的字段一致
     * @return array|callable
     */
    public function add_doc(string $id,array $doc) {
        $params = [
            'index' => 'index',
            'type' => 'type',
            'id' => $id,
            'body' => $doc
        ];
        return $this->client->index($params);
    }

    //获取文档
    public function get_doc(){
        $params = [
            'index' => $this->index_name,
            'type' => $this->type,
            'id'=>1
        ];
       $result = $this->client->get($params);

       return json($result);
    }

    //更新文档
    public function update_doc()
    {
        $params = [
            'index' => $this->index_name,
            'type' => $this->type,
            'id' => 4,
            'body' => [
                'doc' => [
                    'name' => '44444'
                ]
            ]
        ];

        $result = $this->client->update($params);

        return json($result);
    }


    //Bool查询（多条件查询）
    public function many_search_doc()
    {
        $params = [
            'index' => $this->index_name,
            'type' => $this->type,
            'body' => [
                'query' => [
                    'bool' => [
                        'must' => [
                            ['match'=>['name' => 'elasticsearch']],
                            ['match'=>['desc' => '部门2']],
                        ]
                    ],
                ]
            ]
        ];

        $results = $this->client->search($params);

        //搜索结果
        $total = $results['hits']['total']['value'];
        $search_data = $results['hits']['hits'];
        //总条数

        $data = [];
        $data['total'] = $total;
        //数据
        foreach ($search_data as $k=>$v){
            $data['data'][] = $v['_source'];
        }

//        return json($results);
        return json(['status'=>true, 'info'=>'success', 'data'=>$data]);
    }


    /**
     * 查询文档 (分页，排序，权重，过滤)
     * @param $keywords
     * @param int $from
     * @param int $size
     * @return array|callable
     */
    public function search()
    {
        $keywords   = input('keywords');
        $from       = input('from');
        $size       = 10;
        $query      = $this->search_doc1($keywords, $from, $size);
        $params = [
            'index' => $this->index_name,
            'type' => $this->type,
            'body' => $query
        ];

        $response =  $this->client->search($params);
        return json($response);
    }

    /**
     * @param $keywords
     * @param $from
     * @param $size
     * @return array
     */
    public function search_doc1($keywords,$from,$size)
    {
        $data = [];
        $data['from'] = $from;
        $data['size'] = $size;
        $data['sort'] = ['id'=>'desc'];
        if($keywords){
            $data['query'] = [
                "match"=>[
                    "name" => $keywords,        //搜索字段名：name
                ],
            ];
        }

        return $data ;
    }

    /**
     * Scrolling（游标）查询(分页)
     * @return App
     */
    public function scrolling_search_doc()
    {
        $params = [
            "scroll" => "30s",          // 设置游标查询过期时间，不应该太长
            "size" => 10,               // 返回多少数量的文档，作用于单个分片
            "index" => $this->index_name,
            "body" => [
                "query" => [
                    "match_all" => new \stdClass()
                ]
            ]
        ];
        //搜索数据
        $response = $this->client->search($params);
        $data = [];
        //循环读取数据
        foreach ($response['hits']['hits'] as $k=>$v){
            $data[] = $v['_source'];
        }
        //滚动id
        $scroll_id = $response['_scroll_id'];

        return json(['status'=>true, 'info'=>'success', 'data'=>$data, 'scroll_id'=>$scroll_id]);

    }

    /**
     * 使用游标查询下一页：_scroll_id
     * @return \think\response\Json
     */
    public function scrolling_search_doc_two()
    {
//        $scroll_id = 'DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAEAWdW9LUkFoR09UWFdNSFJ1WDR2WnRfZw==';
        $scroll_id = input('scroll_id');
        $response = $this->client->scroll([
            'scroll_id' => $scroll_id,
            'scroll' => '30s'
        ]);

        return json($response);
    }
}